﻿using ProjetoKinect.Model3d;
using ProjetoKinect.Util;
using SharpGL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Media.Media3D;

namespace ProjetoKinect.openGL
{
    class MyOpenGL
    {
        private float[] cosVector;
        public MyOpenGL(int angleCounter)
        {
            cosVector = new float[361];
            for (int i = 0; i <= 360; i++)
            {
                cosVector[i] = getCos(i);
            }
        }

        internal float getCos(int angle)
        {
            double cosDouble = Math.Cos(angle * (Math.PI / 180.0));
            if (cosDouble < 0)
            {
                cosDouble = cosDouble * -1;
            }
            return (float)cosDouble;
        }

        internal void drawnTriangleObjectList(OpenGL gl, List<Model3d.TriangleObject> triangleObjectList, MyPoint3D cameraPosition)
        {
            Vector3D triangleNormal;
            double angleP0;
            float r, g, b, cosP0, finalR, finalG, finalB;
            gl.Clear(OpenGL.GL_DEPTH_BUFFER_BIT);
            gl.Begin(OpenGL.GL_TRIANGLES);
            double subX;
            double subY;
            double subZ;
            foreach (TriangleObject triangleObject in triangleObjectList)
            {
                List<MyTriangle> myTriangleList = triangleObject.getTriangleList();
                double transparency = triangleObject.getTransparency();
                Color color = triangleObject.getColor();
                r = color.R / 255;
                g = color.G / 255;
                b = color.B / 255;
                foreach (MyTriangle myTriangle in myTriangleList)
                {

                    if (transparency == 1)
                    {
                        triangleNormal = myTriangle.getNormal();
                        // subtract vectors and get angle ==angleP0 = myTriangle.getAngleBetween(triangleNormal, myTriangle.getP0().subtractionAsVector3d(cameraPosition));
                        subX = myTriangle.getP0().getX() - cameraPosition.getX();
                        subY = myTriangle.getP0().getY() - cameraPosition.getY();
                        subZ = myTriangle.getP0().getZ() - cameraPosition.getZ();
                        angleP0 = Math.Round(Vector3D.AngleBetween(triangleNormal, new Vector3D(subX, subY, subZ)), 2);
                        if (angleP0.Equals(double.NaN))
                        {
                            angleP0 = 0;
                        }
                        cosP0 = cosVector[(int)angleP0];
                        finalR = r * cosP0;
                        finalG = g * cosP0;
                        finalB = b * cosP0;

                        gl.Color(finalR, finalG, finalB, transparency);
                        gl.Vertex(myTriangle.getP0().getX(), myTriangle.getP0().getY(), myTriangle.getP0().getZ());

                        gl.Color(finalR, finalG, finalB, transparency);
                        gl.Vertex(myTriangle.getP1().getX(), myTriangle.getP1().getY(), myTriangle.getP1().getZ());

                        gl.Color(finalR, finalG, finalB, transparency);
                        gl.Vertex(myTriangle.getP2().getX(), myTriangle.getP2().getY(), myTriangle.getP2().getZ());
                    }
                    else
                    {
                        gl.Color(r, g, b, transparency);
                        gl.Vertex(myTriangle.getP0().getX(), myTriangle.getP0().getY(), myTriangle.getP0().getZ());

                        gl.Color(r, g, b, transparency);
                        gl.Vertex(myTriangle.getP1().getX(), myTriangle.getP1().getY(), myTriangle.getP1().getZ());

                        gl.Color(r, g, b, transparency);
                        gl.Vertex(myTriangle.getP2().getX(), myTriangle.getP2().getY(), myTriangle.getP2().getZ());
                    }

                }
            }

            gl.End();
        }


        internal void initialized(OpenGL gl)
        {
            gl.ClearColor(0, 0, 0, 0);
            gl.Enable(OpenGL.GL_LINE_SMOOTH);
            gl.Disable(OpenGL.GL_CULL_FACE);
            //   gl.Enable(OpenGL.GL_POLYGON_SMOOTH);
            gl.Enable(OpenGL.GL_BLEND);
            gl.Enable(OpenGL.GL_DEPTH_TEST);

            gl.DepthFunc(OpenGL.GL_LESS);
            // gl.ClearDepth(1.0);
            gl.BlendFunc(OpenGL.GL_SRC_ALPHA, OpenGL.GL_ONE_MINUS_SRC_ALPHA);

            gl.LightModel(SharpGL.Enumerations.LightModelParameter.Ambient, 1.0f);
            //    gl.BlendFunc(OpenGL.GL_SRC_ALPHA, OpenGL.GL_ONE_MINUS_SRC_ALPHA);

        }

        internal void resized(OpenGL gl, MyPoint3D cameraPosition, double Width, double Height)
        {
            //  Set the projection matrix.
            gl.MatrixMode(OpenGL.GL_PROJECTION);

            //  Load the identity.
            gl.LoadIdentity();

            //  Create a perspective transformation.
            gl.Perspective(60.0f, (double)Width / (double)Height, 0.1, 150.0);

            //  Use the 'look at' helper function to position and aim the camera.
            MyPoint3D lookAt = cameraPosition.lookToOrign();
            gl.LookAt(cameraPosition.getX(), cameraPosition.getY(), cameraPosition.getZ(), lookAt.getX(), lookAt.getY(), lookAt.getZ(), 0, 1, 0);
            //gl.Enable(OpenGL.GL_CULL_FACE);
            //Set the modelview matrix.
            gl.MatrixMode(OpenGL.GL_MODELVIEW);
        }
    }
}
